﻿using System;
using System.ServiceModel;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Collections.Generic;
using XchangeStreamer.OutputSdk.MarketDataFeedService;
using System.Threading;

namespace XchangeStreamer.OutputSdk.Internal
{
    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
    internal sealed class Callback : IMarketDataFeedCallback, IDisposable
    {
        private BlockingCollection<Message> messages;
        private Dispatcher dispatcher;
        private int disposed = 0;

        public Callback()
        {
            this.messages = new BlockingCollection<Message>();
            this.dispatcher = new Dispatcher();
        }

        public void Publish(Message message)
        {
            Task.Factory.StartNew(() =>
            {
                this.messages.Add(message);
            }, CancellationToken.None, TaskCreationOptions.None, this.dispatcher);
        }

        public IEnumerable<Message> GetEnumerator()
        {
            return this.messages.GetConsumingEnumerable();
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (Interlocked.CompareExchange(ref this.disposed, 1, 0) == 0)
            {
                this.messages.CompleteAdding();

                this.dispatcher.Dispose();
                this.dispatcher = null;
                
                this.messages.Dispose();
                this.messages = null;
            }
        }

        #endregion

        #region IMarketDataFeedCallback Members

        public void GetLineChartIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetBarChartIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetIndicatorChartIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMACDChartIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetCandleChartIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetIndexChartIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetOrderLineChartIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetBestBidAndBestAskChartIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketLiquidityMonitorCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSymbolLiquidityMonitorCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void SymbolVolumeWatchCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketValueRatiosCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetLiquidityRatiosCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetProfitabilityRatiosCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetAssetManagementRatiosCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetDebtManagementRatiosCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetCorporateActionsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMutalFundCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetCompanyEarningsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetInitialPublicOfferingCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetLatestInsiderTradingCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetFairMarketValueCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetLineChartCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetBarChartCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetIndicatorChartCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMACDChartCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetCandleChartCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetIndexChartCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetOrderLineChartCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetBestBidAndBestAskChartCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketIndicesCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketIndexDetailsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetBestPerformersByPriceCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetWorstPerformersByPriceCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetBestPerformersByVolumeCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetWorstPerformersByVolumeCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetBestPerformersByTurnOverCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetWorstPerformersByTurnOverCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketMapCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetInvestorsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarkertFullWatchlistCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetTodayTradesListCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSymbolChangeCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketTimesandSalesIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetTickerCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketSummaryCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketInfoCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMainIndexCompaniesCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSuspendedCompaniesCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketTimesandSalesCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketSectorsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketStatusCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetInstitutionsAndReatailRatios(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetAllNewsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetAnnouncemetsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSymbolAnnouncemetsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSymbolNewsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSectorInfoCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetTimeAndSalesSummaryIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketDepthByPriceCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMarketDepthByOrderCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetBidsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetAsksCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetCumulativeAsksCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetCumulativeBidsCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSymbolCurrentPriceCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSymbolOpenPriceIntraDayCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSymbolInfoCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetTimeAndSalesSummaryCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetSymbolOpenPriceCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetMoneyFlowDetailQuoteCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void GetAverageCostCalculatorInfoCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void CalculateNetChangeForHistoryAnalyzerCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void CalculateExpectedVWAPCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void CalculateSharesToBuyCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void OrderCalculatorCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void CalculateProfitLossValueCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void CalculateProfitLossValueByPriceCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        public void CalculateProfitLossValueForReuterCallBack(byte[] newData)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
